package com.gitee.wsl.android.ui.base

import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

data class Symbol(val type: SymbolType, val color: Int, val size: Dp =5f.dp)

enum class SymbolType {
    NONE,
    SQUARE,
    SQUARE_OUTLINE,
    CIRCLE,
    CIRCLE_OUTLINE,
    TRIANGLE,
    TRIANGLE_OUTLINE,
    DIAMOND,
    DIAMOND_OUTLINE,
    PLUS,
    ASTERISK,
    CROSS,
    CROSS_DIAGONAL,
    SQUARE_SMALL,
    CIRCLE_SMALL,
    UP_ARROW,
    DOWN_ARROW,
    TRIANGLE_DOWN,
    SMALL_DOT,
}

fun Canvas.drawSymbolCentered(symbol: Symbol, width:Float, height:Float, paint:Paint){
    val x = width - symbol.size.value / 2
    val y = height - symbol.size.value / 2
    drawSymbol(symbol, x, y,paint)
}

fun Canvas.fillRect(x: Float, y: Float,width: Float,height: Float,paint: Paint){
    paint.style = Paint.Style.FILL
    drawRect(x,y,x+width,y+height,paint)
}

fun Canvas.fillOval(x: Float, y: Float,width: Float,height: Float,paint: Paint){
    paint.style = Paint.Style.FILL
    drawOval(x,y,x+width,y+height,paint)
}

fun Canvas.fillPolygon(xPointArray: FloatArray, yPointArray: FloatArray, count:Int=3, paint:Paint){
    if(count <= 3 || xPointArray.size != count || xPointArray.size != yPointArray.size) return
    val path = Path()
    path.moveTo(xPointArray[0],yPointArray[0])
    for(i in 1 until  count)
        path.lineTo(xPointArray[i],yPointArray[i])
    path.close()
    drawPath(path, paint)
}

fun Canvas.drawSymbol(symbol: Symbol, x: Float, y: Float, paint:Paint){
    var size = symbol.size.value
    val xc = x + size / 2
    var yc = y + size / 2
    val h: Float
    val xPts: FloatArray
    val yPts: FloatArray
    paint.color = symbol.color
    when (symbol.type) {
        SymbolType.SQUARE_OUTLINE -> this.drawRect(x, y, size - 1, size - 1,paint)
        SymbolType.SQUARE -> this.fillRect(x, y, size, size,paint)
        SymbolType.SQUARE_SMALL -> {
            size -= 2
            this.fillRect(xc - size / 2, yc - size / 2, size, size,paint)
        }

        SymbolType.SMALL_DOT -> {
            size = 2f
            this.fillRect(xc, yc - 1, size, size,paint)
        }

        SymbolType.CIRCLE_SMALL -> {
            size -= 2
            this.fillOval(xc - size / 2, yc - size / 2, size, size,paint)
        }

        SymbolType.CIRCLE -> this.fillOval(x, y, size, size,paint)
        SymbolType.CIRCLE_OUTLINE -> this.drawOval(x, y, size - 1, size - 1,paint)
        SymbolType.CROSS_DIAGONAL, SymbolType.ASTERISK -> {
            this.drawLine(x, y, x + size - 1, y + size - 1,paint)
            this.drawLine(x, y + size - 1, x + size - 1, y,paint)
            if (symbol.type != SymbolType.CROSS_DIAGONAL) {
                this.drawLine(x, yc, x + size - 1, yc,paint)
                this.drawLine(xc, y, xc, y + size - 1,paint)
            }
        }

        SymbolType.CROSS -> {
            this.drawLine(x, yc, x + size - 1, yc,paint)
            this.drawLine(xc, y, xc, y + size - 1,paint)
        }

        SymbolType.PLUS -> {
            // plus looks better at size = 9, so increase size by 2
            var xx = x - 1
            size += 2
            // draw hor line
            var yy = yc - 1
            while (yy < yc + 2) {
                this.drawLine(xx, yy, xx + size - 1, yy,paint)
                yy++
            }
            // draw vert line
            yy = yc - size / 2
            xx = xc - 1
            while (xx < xc + 2) {
                this.drawLine(xx, yy, xx, yy + size - 1,paint)
                xx++
            }
        }

        SymbolType.UP_ARROW -> {
            this.fillRect(xc - 1, yc + 2, 3f, 3f,paint)
            yc -= 1
            size += 2
            val xx = xc - size / 2
            val yy = yc - size / 2 - 1  // move center 1 closer to base
            xPts = FloatArray(3)
            yPts = FloatArray(3)
            xPts[0] = xx
            xPts[1] = xc
            xPts[2] = xx + size - 1
            yPts[0] = yy + size - 1
            yPts[1] = yy
            yPts[2] = yy + size - 1
            this.fillPolygon(xPts, yPts, 3,paint)
            if (symbol.type == SymbolType.UP_ARROW)
                yc += 1
        }

        SymbolType.TRIANGLE -> {
            size += 2
            val xx = xc - size / 2
            val yy = yc - size / 2 - 1
            xPts = FloatArray(3)
            yPts = FloatArray(3)
            xPts[0] = xx
            xPts[1] = xc
            xPts[2] = xx + size - 1
            yPts[0] = yy + size - 1
            yPts[1] = yy
            yPts[2] = yy + size - 1
            this.fillPolygon(xPts, yPts, 3,paint)
            if (symbol.type == SymbolType.UP_ARROW)
                yc += 1
        }

        SymbolType.DOWN_ARROW -> {
            this.fillRect(xc - 1, yc - 4, 3f, 3f,paint)
            yc += 1
            size += 2
            val xx = xc - size / 2
            val yy = yc - size / 2 + 2  // move center 1 closer to base
            xPts = FloatArray(3)
            yPts = FloatArray(3)
            xPts[0] = xx
            xPts[1] = xc
            xPts[2] = xx + size - 1
            yPts[0] = yy
            yPts[1] = yy + size - 1
            yPts[2] = yy
            this.fillPolygon(xPts, yPts, 3,paint)
            if (symbol.type == SymbolType.DOWN_ARROW)
                yc -= 1
        }

        SymbolType.TRIANGLE_DOWN -> {
            size += 2
            val xx = xc - size / 2
            val yy = yc - size / 2 + 2
            xPts = FloatArray(3)
            yPts = FloatArray(3)
            xPts[0] = xx
            xPts[1] = xc
            xPts[2] = xx + size - 1
            yPts[0] = yy
            yPts[1] = yy + size - 1
            yPts[2] = yy
            this.fillPolygon(xPts, yPts, 3,paint)
            if (symbol.type == SymbolType.DOWN_ARROW)
                yc -= 1
        }

        SymbolType.TRIANGLE_OUTLINE -> {
            val yy = y - 1                    // move center 1 closer to base
            this.drawLine(x, yy + size - 1, xc, yy,paint)
            this.drawLine(xc, yy, x + size - 1, yy + size - 1,paint)
            this.drawLine(x + size - 1, yy + size - 1, x, yy + size - 1,paint)
        }

        SymbolType.DIAMOND_OUTLINE -> {
            h = size - 2   // diamond looks better almost twice as tall
            this.drawLine(x, yc, xc, yc - h,paint)
            this.drawLine(xc, yc - h, x + size - 1, yc,paint)
            this.drawLine(x + size - 1, yc, xc, yc + h,paint)
            this.drawLine(xc, yc + h, x, yc,paint)
        }

        SymbolType.DIAMOND -> {
            h = size   // diamond looks better twice as tall
            xPts = FloatArray(4)
            yPts = FloatArray(4)
            xPts[0] = x
            xPts[1] = xc
            xPts[2] = x + size
            xPts[3] = xc
            yPts[0] = yc
            yPts[1] = yc - h
            yPts[2] = yc
            yPts[3] = yc + h
            this.fillPolygon(xPts, yPts, 4,paint)
        }

        SymbolType.NONE -> {}
    }
}